package com.fw.system.web.service.impl;

import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fw.common.Builder;
import com.fw.common.IdXD;
import com.fw.constant.Constant;
import com.fw.system.web.dao.FwIdentityMapper;
import com.fw.system.web.dao.FwMoneysMapper;
import com.fw.system.web.model.entity.*;
import com.fw.system.web.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 身份表 服务实现类
 * </p>
 *
 * @author
 * @since 2021-05-10
 */
@Service
@EnableAsync
public class FwIdentityServiceImpl extends ServiceImpl<FwIdentityMapper, FwIdentity> implements IFwIdentityService {
    @Autowired
    private FwIdentityMapper fwIdentityMapper;

    @Autowired
    private IFwUserService userService;

    @Autowired
    private IFwUljoinService uljoinService;

    @Autowired
    private IFwLogsService logsService;

    @Autowired
    private IFwRuleDatasService ruleDatasService;

    @Autowired
    private IdXD idXD;

    @Autowired
    private IFwMoneysService moneysService;

    @Autowired
    private IFwShangjiaService shangjiaService;
    @Autowired
    private IFwCurrencyLogService currencyLogService;
    @Autowired
    private FwMoneysMapper moneysMapper;
    @Autowired
    private IFwShangjiaReleaseLogService releaseLogService;
    @Autowired
    private IFwShangjiaCreateLogService createLogService;
    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;


    /**
     * todo 获取用户累计消费记录,查询条件需要加上收支类型,消费模板    每当用户产生消费,调用此方法
     * 新增用户vip身份
     *
     * @param fwUser
     */
    @Override
    //@Transactional(rollbackFor = Exception.class)
    public void addIdentity(FwUser fwUser) {

        //获取成为vip所需要消费的数据
        BigDecimal ruleCount = ruleDatasService.getOne(Wrappers.<FwRuleDatas>lambdaQuery()
                .eq(FwRuleDatas::getId, Constant.IsRuleData.VIP_MONEY_ID)).getRuleCount();
        //获取用户所有身份数据,判断用户是否已经拥有vip身份
        FwUljoin uljoin = uljoinService.getOne(Wrappers.<FwUljoin>lambdaQuery()
                .eq(FwUljoin::getUserId, fwUser.getId())
                .eq(FwUljoin::getIsUse, 1));

        //用来记录用户返消证和原始数量的日志,用来判断是否是每满一千送一个商甲的条件
        //如果在消费产出送vip阶段
        FwCurrencyLog currencyLog = new FwCurrencyLog();
        currencyLog = currencyLogService.getOne(Wrappers.<FwCurrencyLog>lambdaQuery()
                .eq(FwCurrencyLog::getLogType, 1).eq(FwCurrencyLog::getUserId, fwUser.getId()));
        if (currencyLog == null) {
            currencyLog = currencyLogService.getOne(Wrappers.<FwCurrencyLog>lambdaQuery()
                    .eq(FwCurrencyLog::getLogType, 2).eq(FwCurrencyLog::getUserId, fwUser.getId()));
        }
        //查询产出标记日志
        FwCurrencyLog createSj = currencyLogService.getOne(Wrappers.<FwCurrencyLog>lambdaQuery().eq(FwCurrencyLog::getLogType, 3));
        if (uljoin != null && currencyLog != null) {
            if (currencyLog.getLogType().equals(1)) {
                currencyLog.setLogType(2);
                currencyLogService.updateById(currencyLog);
            }
        }
        if (currencyLog != null && currencyLog.getLogType().equals(1)) {
            //如果达到送vip产出添加 送商甲
            if (currencyLog.getLogCount().compareTo(ruleCount) >= 0) {
                if (uljoin == null) {
                    //新增用户vip身份,
                    FwUljoin fwUljoin = new FwUljoin()
                            .setSysCode(Constant.Identity.VIP_ID)
                            .setIdentityId(Constant.Identity.VIP_ID)
                            .setCreateTime(LocalDateTime.now())
                            .setUserId(fwUser.getId())
                            .setCreateBy(fwUser.getId());

                    //写入数据库
                    fwUljoin.setIsUse(Constant.IsUsr.IS_USR);
                    fwUljoin.setId(idXD.nextId());
                    uljoinService.save(fwUljoin);
                }
                //发放商甲给用户
                //todo 消费商甲每出20个，原始商甲释放出2个，技术释放1个  管理释放1个
                FwMoneys moneys = moneysService.getOne(Wrappers.<FwMoneys>lambdaQuery().eq(FwMoneys::getUserId, fwUser.getId()));
                moneys.setShangJia(moneys.getShangJia().add(new BigDecimal("1")));//用户商甲加一
                //moneysService.update(Wrappers.<FwMoneys>lambdaUpdate().set(FwMoneys::getShangJia,moneys.getShangJia()).eq(FwMoneys::getId,moneys.getId()));
                moneysMapper.updateById(moneys);
                FwShangjia shangjia = shangjiaService.getOne(Wrappers.<FwShangjia>lambdaQuery().eq(FwShangjia::getId, Constant.ShangJia.CONSUME_ID));
                BigDecimal shopIssue = shangjia.getShopIssue();
                BigDecimal subtract = shopIssue.subtract(new BigDecimal("1"));//消费产出的商甲减一
                shangjia.setShopIssue(subtract);//设置减一后的值
                shangjiaService.updateById(shangjia);
                //增加日志
                FwShangjiaCreateLog createLog = Builder.of(FwShangjiaCreateLog::new).
                        with(FwShangjiaCreateLog::setId, idXD.nextId())
                        .with(FwShangjiaCreateLog::setCreateTime, LocalDateTime.now())
                        .with(FwShangjiaCreateLog::setLogType, 1)
                        .with(FwShangjiaCreateLog::setLogCount, new BigDecimal(1))
                        .with(FwShangjiaCreateLog::setLogName, "消费商甲产出")
                        .with(FwShangjiaCreateLog::setUserId, fwUser.getId())
                        .with(FwShangjiaCreateLog::setPhone, userService.getById(fwUser.getId()).getPhone()).build();
                createLogService.save(createLog);
                //todo 成为vip之后判断一下上级是否需要升级身份并修改释放比例,如果上级是代理就不改了
                userService.bindingParent(fwUser);
                //更新标识日志
                currencyLog.setLogCount(currencyLog.getLogCount().subtract(ruleCount));
                currencyLog.setLogType(2);
                currencyLog.setLogName("满1000消证送商甲阶段");
                currencyLogService.updateById(currencyLog);
                //调用锁仓
                moneysService.extracted(moneys.getUserId(), moneys);


            }

        } else if (currencyLog != null && currencyLog.getLogType().equals(2)) {
            //判断每次是否满1000
            //增加后的
            long forCount = 0;
            //todo 消费商甲每出20个，原始商甲释放出2个，技术释放1个  管理释放1个
            BigDecimal newNum = currencyLog.getLogCount();
            FwMoneys moneys = new FwMoneys();
            if (newNum.compareTo(new BigDecimal(1000)) >= 0) {
                BigDecimal divide = newNum.divide(new BigDecimal("1000"), 5, BigDecimal.ROUND_HALF_UP);
                forCount = divide.setScale(0, BigDecimal.ROUND_DOWN).longValue();
                for (int i = 0; i < forCount; i++) {
                    //BigDecimal addShangjia = newNum.divide(new BigDecimal("1000"), 0, BigDecimal.ROUND_DOWN);
                    //发放商甲给用户
                    moneys = moneysService.getOne(Wrappers.<FwMoneys>lambdaQuery().eq(FwMoneys::getUserId, fwUser.getId()));
                    BigDecimal sourceShangjia = moneys.getShangJia().add(NumberUtil.add(1D));//用户商甲加一
                    moneys.setShangJia(sourceShangjia);
                    moneysMapper.updateById(moneys);
                    FwShangjia shangjia = shangjiaService.getOne(Wrappers.<FwShangjia>lambdaQuery().eq(FwShangjia::getId, Constant.ShangJia.CONSUME_ID));
                    BigDecimal shopIssue = shangjia.getShopIssue();
                    BigDecimal subtract = shopIssue.subtract(NumberUtil.add(1D));//消费产出的商甲减一
                    shangjia.setShopIssue(subtract);//设置减一后的值
                    shangjiaService.updateById(shangjia);
                    //新增阶段日志
                }
                FwShangjiaCreateLog createLog = Builder.of(FwShangjiaCreateLog::new).
                        with(FwShangjiaCreateLog::setId, idXD.nextId())
                        .with(FwShangjiaCreateLog::setCreateTime, LocalDateTime.now())
                        .with(FwShangjiaCreateLog::setLogType, 1)
                        .with(FwShangjiaCreateLog::setLogCount, new BigDecimal(forCount))
                        .with(FwShangjiaCreateLog::setLogName, "消费商甲产出")
                        .with(FwShangjiaCreateLog::setUserId, fwUser.getId())
                        .with(FwShangjiaCreateLog::setPhone, userService.getById(fwUser.getId()).getPhone()).build();
                createLogService.save(createLog);
                //更新标识日志
                currencyLog.setLogCount(newNum.subtract(new BigDecimal(forCount).multiply(new BigDecimal(1000))));
                currencyLog.setLogType(2);//进入下个阶段
                currencyLog.setLogName("满1000消证送商甲阶段");
                currencyLogService.updateById(currencyLog);
                //调用锁仓
                moneysService.extracted(moneys.getUserId(), moneys);
            }
        }

        //更新或新增产出标记日志,用来标记达到数量后去释放技术等商甲
        if (createSj == null) {
            FwCurrencyLog build = Builder.of(FwCurrencyLog::new).with(FwCurrencyLog::setId, idXD.nextId()).
                    with(FwCurrencyLog::setCreateTime, LocalDateTime.now()).
                    with(FwCurrencyLog::setLogCount, new BigDecimal(1)).
                    with(FwCurrencyLog::setInfoFrom, null).with(FwCurrencyLog::setLogName, "商甲产出标记数量日志").
                    with(FwCurrencyLog::setUserId, null).with(FwCurrencyLog::setLogType, 3).build();
            currencyLogService.save(build);
        } else {
            createSj.setLogCount(createSj.getLogCount().add(new BigDecimal(1)));
            currencyLogService.updateById(createSj);
            if (createSj.getLogCount().compareTo(new BigDecimal("20")) >= 0) {
               /* BigDecimal divide = createSj.getLogCount().divide(new BigDecimal("20"), 5, BigDecimal.ROUND_HALF_UP);
                long deleteNum = divide.setScale(0, BigDecimal.ROUND_DOWN).longValue();*/
                //释放商甲技术管理等
                createSj.setLogCount(createSj.getLogCount().subtract(new BigDecimal(20)));
                //todo 开始释放给各个用户
                //获取技术、管理、原始权限人员0 = 普通用户，1= 技术，2= 管理,3=原始的钱包表
                ArrayList<FwMoneys> arrayList = new ArrayList<>();
                FwMoneys typeOne = moneysService.getOne(Wrappers.<FwMoneys>lambdaQuery().
                        eq(FwMoneys::getUserId, userService.getOne(Wrappers.<FwUser>lambdaQuery().eq(FwUser::getIsAccount, 1)).getId()));
                typeOne.setTecShangjia(typeOne.getTecShangjia().add(new BigDecimal(1)));
                //调用锁仓
                moneysService.extracted(typeOne.getUserId(), typeOne);
                arrayList.add(typeOne);
                //moneysService.updateById(typeOne);
                FwMoneys typeTwo = moneysService.getOne(Wrappers.<FwMoneys>lambdaQuery().
                        eq(FwMoneys::getUserId, userService.getOne(Wrappers.<FwUser>lambdaQuery().eq(FwUser::getIsAccount, 2)).getId()));
                typeTwo.setManShangjia(typeOne.getManShangjia().add(new BigDecimal(1)));
                //调用锁仓
                moneysService.extracted(typeTwo.getUserId(), typeTwo);
                arrayList.add(typeTwo);
                FwMoneys typeThree = moneysService.getOne(Wrappers.<FwMoneys>lambdaQuery().
                        eq(FwMoneys::getUserId, userService.getOne(Wrappers.<FwUser>lambdaQuery().eq(FwUser::getIsAccount, 3)).getId()));
                typeThree.setShangJia(typeThree.getShangJia().add(new BigDecimal(2)));
                //调用锁仓
                moneysService.extracted(typeThree.getUserId(), typeThree);
                arrayList.add(typeThree);
                moneysService.updateBatchById(arrayList);
                //增加释放明细
                FwShangjiaReleaseLog oneLog = Builder.of(FwShangjiaReleaseLog::new).with(FwShangjiaReleaseLog::setId, idXD.nextId())
                        .with(FwShangjiaReleaseLog::setCreateTime, LocalDateTime.now())
                        .with(FwShangjiaReleaseLog::setLogType, 1)
                        .with(FwShangjiaReleaseLog::setLogCount, new BigDecimal(1))
                        .with(FwShangjiaReleaseLog::setLogName, "技术释放商甲")
                        .with(FwShangjiaReleaseLog::setUserId, userService.getById(typeOne.getUserId()).getId())
                        .with(FwShangjiaReleaseLog::setPhone, userService.getById(typeOne.getUserId()).getPhone()).build();
                releaseLogService.save(oneLog);
                FwShangjiaReleaseLog oneLog1 = Builder.of(FwShangjiaReleaseLog::new).with(FwShangjiaReleaseLog::setId, idXD.nextId())
                        .with(FwShangjiaReleaseLog::setCreateTime, LocalDateTime.now())
                        .with(FwShangjiaReleaseLog::setLogType, 2)
                        .with(FwShangjiaReleaseLog::setLogCount, new BigDecimal(1))
                        .with(FwShangjiaReleaseLog::setLogName, "管理释放商甲")
                        .with(FwShangjiaReleaseLog::setUserId, userService.getById(typeTwo.getUserId()).getId())
                        .with(FwShangjiaReleaseLog::setPhone, userService.getById(typeTwo.getUserId()).getPhone()).build();
                releaseLogService.save(oneLog1);
                FwShangjiaReleaseLog oneLog2 = Builder.of(FwShangjiaReleaseLog::new).with(FwShangjiaReleaseLog::setId, idXD.nextId())
                        .with(FwShangjiaReleaseLog::setCreateTime, LocalDateTime.now())
                        .with(FwShangjiaReleaseLog::setLogType, 3)
                        .with(FwShangjiaReleaseLog::setLogCount, new BigDecimal(2))
                        .with(FwShangjiaReleaseLog::setLogName, "原始释放商甲")
                        .with(FwShangjiaReleaseLog::setUserId, userService.getById(typeThree.getUserId()).getId())
                        .with(FwShangjiaReleaseLog::setPhone, userService.getById(typeThree.getUserId()).getPhone()).build();
                releaseLogService.save(oneLog2);
                //扣去各个仓的数量
                shangjiaService.list().forEach(item -> {
                    if (item.getId().equals("3"))
                        shangjiaService.updateById(item.setShopIssue(item.getShopIssue().subtract(oneLog2.getLogCount())));
                    if (item.getId().equals("4"))
                        shangjiaService.updateById(item.setShopIssue(item.getShopIssue().subtract(oneLog.getLogCount())));
                    if (item.getId().equals("5"))
                        shangjiaService.updateById(item.setShopIssue(item.getShopIssue().subtract(oneLog1.getLogCount())));
                });
            } else {
                //未达到释放标准,先不释放累计标识数量
                createSj.setLogCount(createSj.getLogCount().add(new BigDecimal(1)));
            }
            currencyLogService.updateById(createSj);
        }
        //更新阶段标识日志
    }


    /**
     * 查询身份
     *
     * @param id 身份ID
     * @return 身份
     */
    @Override
    public FwIdentity selectFwIdentityById(String id) {
        return fwIdentityMapper.selectFwIdentityById(id);
    }

    /**
     * 查询身份列表
     *
     * @param fwIdentity 身份
     * @return 身份
     */
    @Override
    public List<FwIdentity> selectFwIdentityList(FwIdentity fwIdentity) {
        return fwIdentityMapper.selectFwIdentityList(fwIdentity);
    }

    /**
     * 新增身份
     *
     * @param fwIdentity 身份
     * @return 结果
     */
    @Override
    public int insertFwIdentity(FwIdentity fwIdentity) {
        fwIdentity.setCreateTime(LocalDateTime.now());
        fwIdentity.setId(idXD.nextId());
        return fwIdentityMapper.insertFwIdentity(fwIdentity);
    }

    /**
     * 修改身份
     *
     * @param fwIdentity 身份
     * @return 结果
     */
    @Override
    public int updateFwIdentity(FwIdentity fwIdentity) {
        fwIdentity.setUpdateTime(LocalDateTime.now());
        return fwIdentityMapper.updateFwIdentity(fwIdentity);
    }

    /**
     * 批量删除身份
     *
     * @param ids 需要删除的身份ID
     * @return 结果
     */
    @Override
    public int deleteFwIdentityByIds(String[] ids) {
        return fwIdentityMapper.deleteFwIdentityByIds(ids);
    }

    /**
     * 删除身份信息
     *
     * @param id 身份ID
     * @return 结果
     */
    @Override
    public int deleteFwIdentityById(String id) {
        return fwIdentityMapper.deleteFwIdentityById(id);
    }
}

